﻿@using System.Text;
@using Microsoft.Extensions.Options;
@using Microsoft.Extensions.Configuration;
@using Microsoft.Extensions.DependencyInjection;
@using Microsoft.AspNetCore.Hosting;
@using Microsoft.AspNetCore.Identity;
@using BlazorBlogs.Data;
@using BlazorBlogs.Data.Models;
@using Microsoft.EntityFrameworkCore;
@using BlazorBlogsLibrary.Classes.Imports;
@inject IOptions<ConnectionStrings> ConnectionStrings
@inject IWritableOptions<ConnectionStrings> connectionString
@inject IConfiguration configRoot
@inject IWebHostEnvironment hostEnvironment
@inject BlazorBlogsContext context
@inject GeneralSettingsService _GeneralSettingsService
@if (ShowPopup)
{
    <div class="modal" tabindex="-1" style="display:block" role="dialog">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h3 class="modal-title">Edit Connection</h3>
                    <!-- Button to close the popup -->
                    <button type="button" class="close"
                            @onclick="ClosePopup">
                        <span aria-hidden="true">X</span>
                    </button>
                </div>
                <div class="modal-body">
                    <table class="form-group" cellpadding="4" cellspacing="4">
                        <tbody>
                            <tr>
                                <td>
                                    <label for="Title" class="control-label" style="font-weight: bold">Server: </label>
                                </td>
                                <td>
                                    <input type="text" id="ServerName" class="form-control" @bind="ServerName" />
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <label for="Title" class="control-label" style="font-weight: bold">Database: </label>
                                </td>
                                <td>
                                    <input type="text" id="DatabaseName" class="form-control" @bind="DatabaseName" />
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <label for="Title" class="control-label" style="font-weight: bold">Integrated Security: </label>
                                </td>
                                <td>
                                    <select class="form-control"
                                            @bind="IntegratedSecurityDisplay">
                                        @foreach (var option in OptionsTrueFalse)
                                        {
                                            <option value="@option">
                                                @option
                                            </option>
                                        }
                                    </select>
                                </td>
                            </tr>
                            @if (IntegratedSecurityDisplay == "False")
                            {
                                <tr>
                                    <td>
                                        <label for="Title" class="control-label" style="font-weight: bold">Database Username: </label>
                                    </td>
                                    <td>
                                        <input type="text" id="DatabaseUsername" class="form-control" @bind="DatabaseUsername" />
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <label for="Title" class="control-label" style="font-weight: bold">Database Password: </label>
                                    </td>
                                    <td>
                                        <input type="password" id="DatabasePassword" class="form-control" @bind="DatabasePassword" />
                                    </td>
                                </tr>
                            }
                        </tbody>
                    </table>

                    <table class="form-group" cellpadding="4" cellspacing="4">
                        <tbody>
                            <tr>
                                <td>
                                    &nbsp;
                                </td>
                                <td>
                                    @if (boolProcessing == false)
                                    {
                                        <button type="button" label="Set Database Connection"
                                                class="btn btn-success"
                                                @onclick="setConnection">
                                            Set Connection
                                        </button> <span>&nbsp;</span>
                                        @if (DatabaseConnectionState == ConnectionState.Update)
                                        {
                                            <button type="button" label="Delete Database Connection"
                                                    class="btn btn-danger"
                                                    @onclick="deleteConnection">
                                                Delete Connection
                                            </button>
                                        }
                                        <h4>@strStatusMessage</h4>
                                    }
                                    else
                                    {
                                        <RadzenProgressBar Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" Style="margin-bottom: 20px" />
                                        <span>Processing...</span>
                                    }
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>

    @if (ConFirmDeletePopup)
    {
        <div class="modal" tabindex="-1" style="display:block;background-color:gainsboro" role="dialog">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3 class="modal-title">Delete Connection?</h3>
                    </div>
                    <div class="modal-body">
                        <button class="btn btn-primary"
                                @onclick="DeleteYes">
                            Yes
                        </button> <span>&nbsp;</span>
                        <button class="btn btn-danger"
                                @onclick="DeleteNo">
                            No
                        </button>
                    </div>
                </div>
            </div>
        </div>
    }
}
@code {
    // DatabaseConfigurationChanged is an EventCallback that will
    // notify the parent component DatabaseConfiguration Is complete
    [Parameter] public EventCallback<DTOConnectionSetting> DatabaseConfigurationChanged { get; set; }

    [Parameter] public DTOConnectionSetting paramConnectionSetting { get; set; }

    private DTOConnectionSetting connectionSetting = new DTOConnectionSetting();
    string IntegratedSecurityDisplay = "False";
    public bool ConFirmDeletePopup = false;
    List<string> OptionsTrueFalse = new List<string>() { "True", "False" };
    string strStatusMessage = "";
    bool boolProcessing = false;
    bool ShowPopup = false;
    private string DatabaseName = "";
    private string ServerName = "";
    private string DatabaseUsername = "";
    private string DatabasePassword = "";
    private ConnectionState DatabaseConnectionState;

    public void setConnectionParameter(DTOConnectionSetting paramConnectionSetting)
    {
        DatabaseName = paramConnectionSetting.DatabaseName;
        ServerName = paramConnectionSetting.ServerName;
        DatabaseUsername = paramConnectionSetting.Username;
        DatabasePassword = paramConnectionSetting.Password;
        IntegratedSecurityDisplay = (paramConnectionSetting.IntegratedSecurity) ? "True" : "False";
        DatabaseConnectionState = paramConnectionSetting.ConnectionState;

        strStatusMessage = "";
        ConFirmDeletePopup = false;

        // Open the Popup
        ShowPopup = true;
    }

    private async void setConnection()
    {
        boolProcessing = true;
        strStatusMessage = "";

        connectionSetting.DatabaseName = DatabaseName;
        connectionSetting.IntegratedSecurity = Convert.ToBoolean(IntegratedSecurityDisplay);
        connectionSetting.Password = DatabasePassword;
        connectionSetting.ServerName = ServerName;
        connectionSetting.Username = DatabaseUsername;
        connectionSetting.ConnectionState = DatabaseConnectionState;

        var result = await SetConnectionSetting(connectionSetting);

        if (result.Success)
        {
            // Close the Popup
            ShowPopup = false;

            // Notify parent component
            await DatabaseConfigurationChanged.InvokeAsync(connectionSetting);
        }
        else
        {
            strStatusMessage = result.StatusMessage;
        }

        boolProcessing = false;
        StateHasChanged();
    }

    void deleteConnection()
    {
        ConFirmDeletePopup = true;
    }

    void ClosePopup()
    {
        // Close the Popup
        ShowPopup = false;
    }

    void DeleteNo()
    {
        ConFirmDeletePopup = false;
    }

    async Task DeleteYes()
    {
        connectionSetting.DatabaseName = DatabaseName;
        connectionSetting.IntegratedSecurity = Convert.ToBoolean(IntegratedSecurityDisplay);
        connectionSetting.Password = DatabasePassword;
        connectionSetting.ServerName = ServerName;
        connectionSetting.Username = DatabaseUsername;
        connectionSetting.ConnectionState = ConnectionState.Delete;

        // Close the Popup
        ShowPopup = false;

        // Notify parent component
        await DatabaseConfigurationChanged.InvokeAsync(connectionSetting);
    }

    // Utility

    #region public async Task<DTOStatus> SetConnectionSetting(DTOConnectionSetting objConnectionSetting)
    public async Task<DTOStatus> SetConnectionSetting(DTOConnectionSetting objConnectionSetting)
    {
        // The return message
        DTOStatus objDTOStatus = new DTOStatus();
        objDTOStatus.Success = true;

        // Create a Database connection string
        string strConnectionString = CreateDatabaseConnectionString(objConnectionSetting);

        // Test the database connection string
        if (!await DatabaseConnectionValid(strConnectionString))
        {
            // Bad connection setting
            objDTOStatus.Success = false;
            objDTOStatus.StatusMessage = "Connection settings are not valid";
        }

        // Return the result
        return objDTOStatus;
    }
    #endregion

    #region private async Task<bool> DatabaseConnectionValid(string strConnectionString)
    private async Task<bool> DatabaseConnectionValid(string strConnectionString)
    {
        bool boolDatabaseConnectionValid = false;

        // Try to connect to the database
        var optionsBuilder = new DbContextOptionsBuilder<BlazorBlogsContext>();
        optionsBuilder.UseSqlServer(strConnectionString);

        using (var context = new BlazorBlogsContext(optionsBuilder.Options))
        {
            try
            {
                boolDatabaseConnectionValid = await context.Database.CanConnectAsync();
            }
            catch
            {
                boolDatabaseConnectionValid = false;
            }
        }

        return boolDatabaseConnectionValid;
    }
    #endregion

    #region private string CreateDatabaseConnectionString(DTOConnectionSetting objConnectionSetting)
    private string CreateDatabaseConnectionString(DTOConnectionSetting objConnectionSetting)
    {
        StringBuilder SB = new StringBuilder();
        string strConnectionString = "";

        string strUserInfo = (!objConnectionSetting.IntegratedSecurity) ?
            String.Format("uid={0};pwd={1}",
            objConnectionSetting.Username,
            objConnectionSetting.Password) :
            "integrated security=True";

        strConnectionString = String.Format("{0}data source={1};initial catalog={2};{3}",
            SB.ToString(),
            objConnectionSetting.ServerName,
            objConnectionSetting.DatabaseName,
            strUserInfo);

        return strConnectionString;
    }
    #endregion

}
